package com.tencreat.service.account.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.cglib.CglibUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.tencreat.common.constant.MallConstants;
import com.tencreat.common.constant.UserConstants;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.domain.entity.SysDept;
import com.tencreat.common.core.domain.entity.SysRole;
import com.tencreat.common.core.domain.entity.SysUser;
import com.tencreat.common.core.domain.model.ReqIdParam;
import com.tencreat.common.core.domain.model.ReqIdsParam;
import com.tencreat.common.enums.BalanceBusinessType;
import com.tencreat.common.enums.UserType;
import com.tencreat.common.enums.mall.AllEnum;
import com.tencreat.common.exception.CustomException;
import com.tencreat.common.utils.SecurityUtils;
import com.tencreat.common.utils.StringUtils;
import com.tencreat.common.utils.uuid.IdUtils;
import com.tencreat.domain.account.MallSupplier;
import com.tencreat.domain.account.MallUser;
import com.tencreat.domain.account.dto.AccountRegisterDTO;
import com.tencreat.domain.account.dto.MallSupplierRequDTO;
import com.tencreat.domain.account.dto.MallSupplierDTO;
import com.tencreat.domain.account.vo.MallSupplierRespVo;
import com.tencreat.domain.account.vo.MallSupplierStaticsVo;
import com.tencreat.domain.mall.BalanceChange;
import com.tencreat.domain.mall.MallComment;
import com.tencreat.domain.mall.dto.MallSupplierAuditDTO;
import com.tencreat.mapper.account.MallSupplierMapper;
import com.tencreat.mapper.system.SysDeptMapper;
import com.tencreat.service.account.IMallRegionService;
import com.tencreat.service.account.IMallSupplierService;
import com.tencreat.service.account.IMallSystemService;
import com.tencreat.service.account.IMallUserService;
import com.tencreat.service.mall.IBalanceChangeService;
import com.tencreat.service.system.ISysMessageService;
import com.tencreat.service.system.ISysRoleService;
import com.tencreat.service.system.ISysUserService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 供应商Service业务层处理
 *
 * @author tencreat
 * @date 2021-08-13
 */
@Service
public class MallSupplierServiceImpl extends ServiceImpl<MallSupplierMapper, MallSupplier> implements IMallSupplierService {

	@Autowired
	private IMallSystemService mallSystemService;
	@Autowired
	private ISysUserService userService;
	@Autowired
	private AccountLoginCheckServiceImpl accountLoginCheckService;
	@Autowired
	private ISysRoleService roleService;
	@Autowired
	private RedissonClient redissonClient;
	@Autowired
	private IMallRegionService regionService;
	@Autowired
	private ISysMessageService sysMessageService;
	@Autowired
	private SysDeptMapper deptMapper;
	@Autowired
	private IMallUserService mallUserService;
	@Autowired
	private IBalanceChangeService balanceChangeService;

	/**
	 * 查询供应商
	 *
	 * @param id 供应商ID
	 * @return 供应商
	 */
	@Override
	public MallSupplier selectMallSupplierById(ReqIdParam id) {
		MallSupplier mallSupplier = baseMapper.selectById(id.getId());
		//根据省市区获取详情信息
		String name = regionService.getNameBycounty(mallSupplier.getCounty());
		mallSupplier.setAreasName(name);
		return mallSupplier;
	}

	/**
	 * 查询供应商
	 *
	 * @param id 供应商ID
	 * @return 供应商
	 */
	@Override
	public MallSupplier selectMallSupplierById(Long id) {
		return baseMapper.selectById(id);
	}

	/**
	 * 查询供应商列表
	 *
	 * @param mallSupplier 供应商
	 * @return 供应商
	 */
	@Override
	public List<MallSupplier> selectMallSupplierList(MallSupplier mallSupplier) {
		return baseMapper.selectList(Wrappers.query(mallSupplier));
	}

	/**
	 * 新增供应商
	 *
	 * @param mallSupplierVO 供应商
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public HttpResult<String> insertMallSupplier(MallSupplierDTO mallSupplierVO) {
		// 根据手机号码查询供应商
		MallUser one = mallUserService.lambdaQuery().eq(MallUser::getUuid, mallSupplierVO.getUuid()).one();
		if (one == null){
			throw new CustomException("该用户不存在");
		}
		mallSupplierVO.setMobile(one.getMobile());
		// 新增供应商
		MallSupplier mallSupplier = CglibUtil.copy(mallSupplierVO, MallSupplier.class);
		mallSupplier.setApprovalStatus(0);
		mallSupplier.setStatus(0);
		mallSupplier.setCreateTime(LocalDateTime.now());
		save(mallSupplier);
		// 审核供应商
		MallSupplierAuditDTO dto = new MallSupplierAuditDTO();
		dto.setId(mallSupplier.getId());
		dto.setType(1);
		dto.setPassword(mallSupplierVO.getPassword());
		audit(dto);
		return HttpResult.ok("新增成功");
	}
	public SysUser insertSysUser(MallSupplier supplier,String pass) {
		SysUser user = new SysUser();
		user.setUserName(supplier.getMobile());
		user.setPhonenumber(supplier.getMobile());
		user.setNickName(supplier.getUsername());
		user.setCreateTime(LocalDateTime.now());
		// 账号绑定固定的供应商角色
		SysRole sysRole = roleService.selectRoleByRoleSupplier("supplier");
		if (sysRole == null) {
			throw new CustomException("没有找到供应商角色");
		}
		Long[] roleIds = { sysRole.getRoleId() };
		user.setRoleIds(roleIds);
		user.setPassword(SecurityUtils.encryptPassword(pass));
		user.setStore(2);
		// 注册账号
		userService.insertUser(user);


		//创建一个属于本人得部门
		SysDept sysDept = new SysDept();
		sysDept.setAncestors("0");
		sysDept.setDeptName(user.getNickName());
		sysDept.setOrderNum("0");
		sysDept.setLeader(user.getNickName());
		sysDept.setPhone(user.getPhonenumber());
		sysDept.setCreateTime(LocalDateTime.now());
		sysDept.setUpdateTime(LocalDateTime.now());
		sysDept.setTenantId(user.getUserId());
		deptMapper.insertDept(sysDept);

		SysUser deptUser = new SysUser();
		deptUser.setUserId(user.getUserId());
		deptUser.setTenantId(user.getUserId());
		deptUser.setDeptId(sysDept.getDeptId());
		userService.updateUserStatus(deptUser);
		return user;
	}
	private void insertAccountLoginCheck(MallSupplierDTO mallSupplierVO) {
		AccountRegisterDTO accountRegisterPO = new AccountRegisterDTO();
		accountRegisterPO.setPassword(mallSupplierVO.getPassword());
		accountRegisterPO.setPhone(mallSupplierVO.getMobile());
		accountRegisterPO.setUsername(mallSupplierVO.getMobile());
		accountRegisterPO.setReferrerUuid(AllEnum.SUPER_UUID);
		accountRegisterPO.setCode(AllEnum.SUPER_CODE);
		accountRegisterPO.setUserType(UserType.ORDINARY.getValue());
		accountLoginCheckService.register(accountRegisterPO);
	}

	/**
	 * 审核供应商
	 *
	 * @param id     供应商ID
	 * @param passed 是否审核通过
	 * @return 结果
	 */
	@Override
	@Deprecated
	public HttpResult<String> auditMallSupplier(ReqIdParam id, Boolean passed) {
		MallSupplier mallSupplier = baseMapper.selectById(id.getId());
		if (mallSupplier == null || !mallSupplier.getApprovalStatus().equals(0) || passed == null) {
			return HttpResult.ok("无法修改");
		}
		if (passed) {
			mallSupplier.setApprovalStatus(1);
			sysMessageService.auditMallSupplier(mallSupplier.getMobile(), mallSystemService.selectMallSystemByName("供应商审核成功消息").getKeyValue());
		} else {
			mallSupplier.setApprovalStatus(2);
		}
		baseMapper.updateById(mallSupplier);
		return HttpResult.ok("修改成功");
	}

	@Override
	public HttpResult<Boolean> password(MallSupplierRequDTO mallSupplier) {
		SysUser user = userService.selectUserById(mallSupplier.getUserId());
		user.setPassword(SecurityUtils.encryptPassword(mallSupplier.getPassword()));

//		AccountLoginCheck one = accountLoginCheckService.lambdaQuery().eq(AccountLoginCheck::getPhone, user.getPhonenumber()).one();
//		one.setPassword(Md5Utils.hash(mallSupplier.getPassword()));
//		accountLoginCheckService.updateAccountLoginCheck(one);

		// 账号绑定固定的供应商角色
//		SysRole sysRole = roleService.selectRoleByRoleSupplier("supplier");
//		if (sysRole == null) {
//			throw new CustomException("没有找到供应商角色");
//		}
//		Long[] roleIds = { sysRole.getRoleId() };
//		user.setRoleIds(roleIds);
		return HttpResult.ok(userService.updateUserStatus(user) > 0);
	}

	/**
	 * 修改供应商
	 *
	 * @param mallSupplier 供应商
	 * @return 结果
	 */
	@Override
	public HttpResult<String> updateMallSupplier(MallSupplier mallSupplier) {
		mallSupplier.setUpdateTime(LocalDateTime.now());
		baseMapper.updateById(mallSupplier);
		return HttpResult.ok("修改成功");
	}

	/**
	 * 批量删除供应商
	 *
	 * @param ids 需要删除的供应商ID
	 * @return 结果
	 */
	@Override
	public int deleteMallSupplierByIds(ReqIdsParam ids) {
		for(Long id : ids.getId()){
			MallSupplier mallSupplier = baseMapper.selectById(id);
			MallUser one = mallUserService.lambdaQuery().eq(MallUser::getMobile, mallSupplier.getMobile()).one();
			one.setSupplier(Long.valueOf(AllEnum.SupplierGoods.NO.getType()));
			mallUserService.updateById(one);
		}
		return baseMapper.deleteBatchIds(ids.getId());
	}

	/**
	 * 删除供应商信息
	 *
	 * @param id 供应商ID
	 * @return 结果
	 */
	@Override
	public int deleteMallSupplierById(ReqIdParam id) {
		return baseMapper.deleteById(id.getId());
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void audit(MallSupplierAuditDTO dto) {
		String key = "mall_supplier_audit_" + dto.getId();
		RLock lock = redissonClient.getLock(key);
		lock.lock();
		try {
			MallSupplier supplier = lambdaQuery().eq(MallSupplier::getId, dto.getId()).one();
			if (supplier == null || supplier.getApprovalStatus() != 0) {
				throw new CustomException("该数据已操作，请刷新后重试！");
			}
			// 校验
			int count = lambdaQuery().eq(MallSupplier::getUsername, supplier.getUsername()).eq(MallSupplier::getApprovalStatus, 1).count();
			if (count > 0) {
				throw new CustomException("已存在相同供应商名称");
			}
			MallUser mallUser = mallUserService.lambdaQuery().eq(MallUser::getMobile, supplier.getMobile()).one();

			// 审核通过
			if (dto.getType() == 1) {
				// 创建用户密码
				String password = RandomUtil.randomString(6);
				if(StringUtils.isNotEmpty(dto.getPassword())) {
					password = dto.getPassword();
				}
				// 创建一个后台账号
				SysUser user = insertSysUser(supplier,password);
				// 修改审核状态
				LambdaUpdateChainWrapper<MallSupplier> wrapper = lambdaUpdate().eq(MallSupplier::getId, supplier.getId())
						.set(MallSupplier::getUserId, user.getUserId())
						.set(MallSupplier::getAccount, user.getUserName())
						.set(MallSupplier::getStatus,0)
						.set(MallSupplier::getApprovalStatus, dto.getType());
				if(mallUser != null){
					wrapper.set(MallSupplier::getUuid,mallUser.getUuid());
					mallUser.setSupplier(Long.valueOf(AllEnum.SupplierGoods.YES.getType()));
					mallUser.setUserId(user.getUserId());
					mallUserService.lambdaUpdate().eq(MallUser::getId,mallUser.getId())
					.set(MallUser::getSupplier,mallUser.getSupplier())
					.set(MallUser::getUserId,mallUser.getUserId())
					.update();
				}
				wrapper.update();
				// 发送信息
				sysMessageService.smsSupplierApproved(user.getPhonenumber(), user.getUserName(), password);
			}
			// 驳回
			else {
				// 修改审核状态
				lambdaUpdate().eq(MallSupplier::getId, supplier.getId()).set(MallSupplier::getApprovalStatus, 2).update();
			}
		} catch (Exception e) {
			throw e;
		} finally {
			lock.unlock();
		}
	}


	@Override
	public synchronized int generateUUID() {
		while (true) {
			int uuid = IdUtils.generateUUID();
			Integer oldUUID = IdUtils.idCache.get(uuid);
			if (oldUUID == null) {
				int count = lambdaQuery().eq(MallSupplier::getUuid, uuid).count();
				if (count == 0) {
					IdUtils.idCache.put(uuid, uuid);
					return uuid;
				}
			}
		}
	}

	@Override
	public MallSupplierStaticsVo supplierStatics(){
		MallSupplierStaticsVo mallSupplierStaticsVo = new MallSupplierStaticsVo();
		// 获取今天的时间
		LocalDateTime beginOfDay = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
		String Day = DateUtil.format(beginOfDay, "yyyyMMdd");
		// 供应商总数
		Integer totalCount = lambdaQuery().count();
		// 昨日新增供应商总数
		Integer lastTotalCount = lambdaQuery().apply("date_format(create_time,'%Y%m%d') = " + "'" + Day + "'").count();
		// 禁用总数
		Integer disableCount = lambdaQuery().eq(MallSupplier::getStatus, 1).count();
		// 昨日禁用数
		Integer lastDisableCount = lambdaQuery().eq(MallSupplier::getStatus, 1).apply("date_format(create_time,'%Y%m%d') = " + "'" + Day + "'").count();
		// 待审核总数
		Integer auditCount = lambdaQuery().eq(MallSupplier::getApprovalStatus, 0).count();
		// 昨日新增待审核总数
		Integer lastAuditCount = lambdaQuery().eq(MallSupplier::getApprovalStatus, 0).apply("date_format(create_time,'%Y%m%d') = " + "'" + Day + "'").count();
		// 货款总数
		BigDecimal amount = userService.querySupplierEarnings();
		// 昨日新增货款总数
		List<BalanceChange> list = balanceChangeService.lambdaQuery().eq(BalanceChange::getBusinessType, BalanceBusinessType.ORDER_CONFIRM)
				.apply("date_format(create_time,'%Y%m%d') = " + "'" + Day + "'")
				.list();
		double lastAmount = 0;
		if (list != null){
			 lastAmount = Lists.transform(list, l -> l.getChangAmount().doubleValue()).stream().mapToDouble(Double::doubleValue).sum();
		}

		mallSupplierStaticsVo.setAmount(amount != null?amount:BigDecimal.ZERO);
		mallSupplierStaticsVo.setLastAmount(BigDecimal.valueOf(lastAmount));
		mallSupplierStaticsVo.setAuditCount(auditCount != null?auditCount:0);
		mallSupplierStaticsVo.setLastAuditCount(lastAuditCount != null?lastAuditCount:0);
		mallSupplierStaticsVo.setDisableCount(disableCount != null?disableCount:0);
		mallSupplierStaticsVo.setLastDisableCount(lastDisableCount != null?lastDisableCount:0);
		mallSupplierStaticsVo.setLastTotalCount(lastTotalCount != null?lastTotalCount:0);
		mallSupplierStaticsVo.setTotalCount(totalCount != null?totalCount:0);

		return mallSupplierStaticsVo;
	}

	@Override
	public IPage<MallSupplierRespVo> queryAll(Page<MallSupplier> page, MallSupplier supplier){
		if (supplier.getSortDesc() != null && supplier.getSortStr() != null){
			if (supplier.getSortDesc().equals("descending")){
				supplier.setSortDesc("desc");
			}else {
				supplier.setSortDesc("asc");
			}
		}
		return baseMapper.queryAll(page,supplier);
	}

	@Override
	public Long selectApprovalStatus(Long uuid) {
		return baseMapper.selectApprovalStatus(uuid);
	}


	@Override
	public List<MallSupplier> selectByUserName(String userName) {
		return baseMapper.selectByUserName(userName);
	}
}
